/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of LModeller.
 *
 * LModeller is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * LModeller is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LModeller.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.lmodeller.blocks;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

import org.lwjgl.util.vector.Vector3f;

public class BlockBuilder {
	
	public static BlockModel CreateModel(File file) {
		BlockModel model = new BlockModel();

		if(!file.isFile())
		{
            System.err.println("Can't open " + file.getName());
            return null;
		}

        Scanner scanner;
		try {
			scanner = new Scanner(new FileReader(file));
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
			return null;
		}
		model.setName(file.getName().substring(0, file.getName().lastIndexOf('.')));
        try {
            //first use a Scanner to get each line
            while ( scanner.hasNextLine() ){
				Block block = new Block();
				
				if (block.setBlockByLdrFile(scanner.nextLine()))
				{
	                model.addBlock(block);
				}
            }
        }
        finally {
            scanner.close();
        }
        model.processModel();
        
		return model;
	}
	
	public static BlockModel CreateRandomModel(int blockCount) {

		BlockModel model = new BlockModel();
		model.setName("");
		ArrayList<Block> blocks = BlockBox.getBlockBox().getCopyofAllBlocks();
		Random rnd = new SecureRandom();
		
        int currentBlockCount = blockCount;
        if (currentBlockCount > blocks.size())
        {
            currentBlockCount = blocks.size();
        }


        int matrixSize = 10 > (currentBlockCount) ? 10 : (int)currentBlockCount;
        int[][] matrix = new int[matrixSize][matrixSize * 2];

        int i, j, y;
        Block b = null;

        int x = 0;
        int b_lenght = 0;
        int b_half_lenght = 0;
        boolean ok = false;

        for (i = 0; i < currentBlockCount; i++)
        {
        	int index = rnd.nextInt(blocks.size());
            b = blocks.get(index);
            blocks.remove(index);

            if (b != null)
            {
                b_lenght = b.getLenght() / 20;
                b_half_lenght = (int)(b_lenght / 2);
                x = rnd.nextInt(matrixSize-b_lenght) + b_half_lenght;
                ok = false;
                y = 0;
                while (!ok) //y-koordinaatti
                {
                    ok = true;
                    for (j = x - b_half_lenght; j < x + b_half_lenght; j++)
                    {
                        if (matrix[j][y] != 0)
                        {
                            ok = false; //Alueelta löytyi jo palikka
                        }
                    }
                    //Tarkista että ylhäällä tai alhaalla on palikka johon kiinnittyä
                    //muttei molemmissa, ellei ole ensimmäinen palikka
                    if (ok == true && i > 0)
                    {
                        ok = false;
                        boolean foundLow = false;
                        boolean foundHigh = false;
                        for (j = x - b_half_lenght; j < x + b_half_lenght; j++)
                        {
                            int low = y - 1;
                            int high = y + 1;
                            if (low >= 0 && matrix[j][low] != 0)
                            {
                                foundLow = true; //Alhaalta löytyi kosketuspinta
                            }
                            if (high < matrixSize * 2 && matrix[j][high] != 0)
                            {
                                foundHigh = true; //Ylhäältä löytyi kosketuspinta
                            }
                        }
                        if (foundLow != foundHigh)
                        {
                            ok = true;
                        }
                    }
                    if (!ok)
                    {
                        if (y < (matrixSize * 2) - 1)
                        {
                            y++;
                        }
                        else
                        {
                            ok = false;
                            y = 0;
                            x = rnd.nextInt(matrixSize-b_lenght) + b_half_lenght;
                        }
                    }
                }

                b.setLocation(new Vector3f(x*20, y*24, 0*20));
                b.setRotation(0);
                model.addBlock(b);

                for (j = x - (b_half_lenght); j < x + b_half_lenght; j++)
                {
                    matrix[j][y] = 1;
                }
            }

        }

        model.processModel();
		return model;
	}

}
